import { Logger } from "@/utils/logger";
import { NormalColony } from "../../NormalColony";
import config from "./config";
import { getBodyParts } from "./spawn";

export const useConfig = (role: CreepRole, energyAvailable: number, level = 8) => {
    const configItem = config[role];
    if (!configItem) {
        return undefined;
    }
    return {
        role,
        body: getBodyParts(configItem.body, energyAvailable, level),
        name: configItem.name,
        priority: configItem.priority
    } as SpawnRequest;
}

const getHarvestPos = (source: Source) => {
    let num = 0;
    for (const dx of [-1, 0, 1]) {
        for (const dy of [-1, 0, 1]) {
            const pos = new RoomPosition(source.pos.x + dx, source.pos.y + dy, source.pos.roomName);
            num += pos.isPassible() ? 1 : 0;
        }
    }
    return num;
}
const releaseHarvestersForSource = (colony: NormalColony, source: Source, priority = 0) => {
    // 剔除不存在的爬
    const { harvestBind } = colony.memory;
    if (!harvestBind[source.id]) {
        harvestBind[source.id] = [];
    }
    else {
        harvestBind[source.id] = harvestBind[source.id].filter(name => {
            return Game.creeps[name] !== undefined;
        });
    }
    // 如果数量不足，就加入请求
    const expectedNumber = colony.level <= 2 ?
        Math.min(getHarvestPos(source), 3) :
        1;
    const actualNumber =
        harvestBind[source.id].length +
        colony.roleCounter.getSpawningCreeps(CreepRole.harvester, req => {
            return req.data && req.data.target === source.id;
        }).length;
    for (let i = 0; i < expectedNumber - actualNumber; ++i) {
        const requestObj = useConfig(
            CreepRole.harvester,
            colony.capital.energyAvailable,
            colony.level);
        requestObj.data = {
            target: source.id,
        };
        if (priority > 0) {
            requestObj.priority = priority;
        }
        colony.spawnModule.request(requestObj);
    }
}

const manageEarlyCreepSpawning = (colony: NormalColony) => {
    const { capital } = colony;
    const { energyAvailable } = capital;
    switch (colony.memory.spawnStage) {
        // #1 第一个 harvester
        case 1: {
            const source = colony.capital.getSources()[0];
            if (source) {
                const requestObj = useConfig(CreepRole.harvester, energyAvailable, colony.level);
                requestObj.data = {
                    target: source.id,
                    temporary: true
                };
                colony.spawnModule.request(requestObj);
                colony.memory.spawnStage++;
            }
            break;
        }
        // #2 第一个 transporter
        case 2: {
            const requestObj = useConfig(CreepRole.transporter, energyAvailable, colony.level);
            requestObj.data = {
                temporary: true,
            };
            requestObj.body = 'MC'; // 加速初始化 = [MOVE, CARRY]
            colony.spawnModule.request(requestObj);
            colony.memory.spawnStage++;
            break;
        }
        // #3 对每一个 source 发布足够的 harvester
        case 3: {
            // 没有足够的 transporter 就不发布了
            if (colony.roleCounter.countAlive(CreepRole.transporter) <= 0) {
                break;
            }

            // 针对每一个 source 发布组合，并确保一定按顺序
            // 这就有一个问题，不支持测试房间里 3+ 矿，不过问题不大
            const [source0, source1] = colony.capital.getSources();
            // source[0]
            const transporterReq0 = useConfig(CreepRole.transporter, energyAvailable, colony.level);
            transporterReq0.priority = 9;    // 确保运输爬比 harvester 更早产出
            colony.spawnModule.request(transporterReq0);
            releaseHarvestersForSource(colony, source0, 8);
            // source[1]
            if (source1) {
                const transporterReq1 = useConfig(CreepRole.transporter, energyAvailable, colony.level);
                transporterReq1.priority = 7;
                colony.spawnModule.request(transporterReq1);
                releaseHarvestersForSource(colony, source1, 6);
            }
            colony.memory.spawnStage++;
            break;
        }
        // #4 产出更多的 transporter
        case 4: {
            const transporterReq = useConfig(CreepRole.transporter, energyAvailable, colony.level);
            transporterReq.priority = 5;
            colony.spawnModule.request(transporterReq);
            colony.memory.spawnStage++;
            break;
        }
        // #5 产出几个个 worker 并建造一个 battery container
        case 5: {
            // 用于缓冲，防止有太多 request
            if (colony.roleCounter.countAlive(CreepRole.transporter) < 4) { // 之前有 4 个 transporter
                break;
            }

            const workerReq = useConfig(CreepRole.worker, energyAvailable, colony.level);
            colony.spawnModule.request(workerReq);
            colony.spawnModule.request(workerReq);
            colony.spawnModule.request(workerReq);
            // 创建一个 battery container
            const { capital } = colony;
            const sp = colony.structMgr.getSpawn(0)?.pos;
            if (sp) {
                const ret = capital.createConstructionSite(sp.x, sp.y + 2, STRUCTURE_CONTAINER);
                if (ret !== 0) {
                    Logger.warn(`阶段 5 无法创建 battery container 的工地！`, 'autospawn');
                }
                else {
                    colony.memory.spawnStage++;
                }
            }
            else {
                Logger.warn(`阶段 5 无法确定 spawn0 的位置！`, 'autospawn');
            }
            break;
        }
        // #7 产出一个 scout 探索周围，方便开外矿
        case 7: {
            colony.spawnModule.request(useConfig(CreepRole.scout, energyAvailable, 1));
            break;
        }
        // #8 继续产出工人
        case 8: {
            // 产出 scout 之后再产出
            if (colony.roleCounter.countAlive(CreepRole.scout) <= 0) {
                break;
            }

            const workerReq = useConfig(CreepRole.worker, energyAvailable, colony.level);
            colony.spawnModule.request(workerReq);
            colony.spawnModule.request(workerReq);
            colony.spawnModule.request(workerReq);
        }
    }
}

const manageNormalCreepSpawning = (colony: NormalColony) => {
}

export const manageCreepSpawning = (colony: NormalColony) => {
    // 根据 spawnStage 决定 spawn 进度
    if (!colony.memory.spawnStage) {
        // 没有设置，不工作
        return;
    }

    if (colony.memory.spawnStage < 0xff) {
        manageEarlyCreepSpawning(colony);
    }
    else {
        manageNormalCreepSpawning(colony);
    }
}